package br.brpv.silvestrin.vendas.mainactivity;

//TODO quando cria pela primeira vez, está carregando os clientes duas vezes. Uma quando carrega a lista das empresas e outra quando carrega a empresa default

import java.util.ArrayList;

import android.app.Activity;
import android.content.*;
import android.os.Bundle;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import br.brpv.silvestrin.vendas.R;
import br.brpv.silvestrin.vendas.domain.*;
import br.brpv.silvestrin.vendas.listeners.CompanyParamsDefaultQueryListener;
import br.brpv.silvestrin.vendas.manager.OrderManager;
import br.brpv.silvestrin.vendas.util.ShowMessage;
import br.brpv.silvestrin.vendas.webservice.ServerConnection;
import br.brpv.silvestrin.vendas.webservice.ServerDataCacheService;

public class NewOrderFragment extends CompanyFragment implements SelectClientInterface, AddedItemsListInterface,
        FinalizeOrderInterface, CompanyParamsDefaultQueryListener, OrderManager.OrderManagerInterface {

    private static final String SAVE_COD_SELECTED_COMPANY = "saveCodSelectedCompany";

    private enum Mode {SELECT_CLIENT, WAIT_NEW_ORDER, MAKE_ORDER, ENDING_ORDER}

    private ServerDataCacheService mServerDataCacheBinder;
    private boolean mBound;


    private SelectClientScreen selectClientScreen;
    private AddItemsScreen addItemsScreen;
    private FinalizeOrderScreen finalizeOrderScreen;

    private String clientID;
    private String clientCode;
    private String establishmentID;
    private CompanyParameters paramsSelectedCompany;
    private EstabParamsDefault estabParamsDefault;
    private ArrayList<AddedItem> itemsToSend;

    private Order currentOrder;
    private OrderManager orderManager;

    private Mode newOrderCurrentMode = Mode.SELECT_CLIENT;

    @Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

        selectClientScreen = new SelectClientScreen(getActivity(), this);
        addItemsScreen = new AddItemsScreen(getActivity(), this);
        finalizeOrderScreen = new FinalizeOrderScreen(getActivity(), this);

        orderManager = new OrderManager(getActivity(), this);

        setNewOrderMode(newOrderCurrentMode);

        //bind on ServerDataCacheService
        Intent intent = new Intent(getActivity(), ServerDataCacheService.class);
        getActivity().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

        /*if(savedInstanceState != null) {
	 	   ArrayList<Parcelable> savedArray = savedInstanceState.getParcelableArrayList("clientArray");
	 	   ArrayList<Client> clientArray = new ArrayList<Client>();
	 	   
	 	   for(Parcelable p: savedArray) {
	 		   clientArray.add((Client) p);
	 	   }

            codSelectedCompany = savedInstanceState.getInt(SAVE_COD_SELECTED_COMPANY);
	 	   
	 	   initClientsList(clientArray);
	    }*/

	}

    @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View newOrderView = inflater.inflate(R.layout.new_order_layout, container, false);

        LinearLayout selectClientLayout = (LinearLayout)newOrderView.findViewById(R.id.select_client_layout);
        LinearLayout addItemView = (LinearLayout)newOrderView.findViewById(R.id.add_item_layout);
        LinearLayout finalFormView = (LinearLayout)newOrderView.findViewById(R.id.end_order_layout);

        addItemsScreen.setAddItemsView(addItemView);
        finalizeOrderScreen.setFinalFormView(finalFormView);
        selectClientScreen.setSelectClientLayout(selectClientLayout);

        Button newButton = (Button)addItemView.findViewById(R.id.final_consumer_new_order);
        newButton.setVisibility(View.GONE);

        return newOrderView;
   }

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {

        selectClientScreen.initSelectClientScreen();
        addItemsScreen.initAddItemScreen();
        finalizeOrderScreen.initFinalizeOrderScreen();

        setNewOrderMode(newOrderCurrentMode);

		super.onActivityCreated(savedInstanceState);
	}

    @Override
    public void onStart() {
        super.onStart();
        //this code is to fix an android bug
        if(finalizeOrderScreen != null) {
            finalizeOrderScreen.showFinalConsumerFieldsIfNeeded();
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        if (mBound) {
            getActivity().unbindService(mConnection);
            mBound = false;
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
    }

    private ServiceConnection mConnection = new ServiceConnection(){

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            // We've bound to LocalService, cast the IBinder and get LocalService instance
            ServerDataCacheService.LocalBinder localBinder = (ServerDataCacheService.LocalBinder)iBinder;

            mServerDataCacheBinder = localBinder.getService();
            selectClientScreen.setmServerDataCacheBinder(mServerDataCacheBinder);
            addItemsScreen.setmServerDataCacheBinder(mServerDataCacheBinder);
            finalizeOrderScreen.setmServerDataCacheBinder(mServerDataCacheBinder);

            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            selectClientScreen.setmServerDataCacheBinder(null);
            addItemsScreen.setmServerDataCacheBinder(null);
            finalizeOrderScreen.setmServerDataCacheBinder(null);

            mBound = false;
        }
    };


    @Override
	public void onSaveInstanceState(Bundle outState) {
		/*
		ArrayList<Client> clientArray = new ArrayList<Client>();
        if(clientAdapter != null) {
            for(int i = 0; i < clientAdapter.getCount(); i++) {
                clientArray.add(clientAdapter.getItem(i));
            }
        }

		outState.putParcelableArrayList("clientArray", clientArray);
        outState.putInt(SAVE_COD_SELECTED_COMPANY, codSelectedCompany);
		*/
		super.onSaveInstanceState(outState);
	}


    public int getSelectedCompany() {
        return codSelectedCompany;
    }

    public void setSelectedCompany(int codCompany) {

        if(this.codSelectedCompany != codCompany) {
            this.codSelectedCompany = codCompany;

            selectClientScreen.setCodSelectedCompany(codSelectedCompany);
            setNewOrderMode(Mode.SELECT_CLIENT);
            getCompanyParams();
        }
    }

    public void setItemsToSend(ArrayList<AddedItem> itemsToSend) {
        this.itemsToSend = itemsToSend;
    }

    private void setNewOrderMode(Mode mode){
        switch (mode) {
            case SELECT_CLIENT:
                newOrderCurrentMode = Mode.SELECT_CLIENT;
                if(selectClientScreen!=null) selectClientScreen.setVisible();
                if(addItemsScreen != null) addItemsScreen.setInvisible();
                if(finalizeOrderScreen != null) finalizeOrderScreen.setInvisible();
                break;
            case MAKE_ORDER:
                newOrderCurrentMode = Mode.MAKE_ORDER;
                if(selectClientScreen!=null) selectClientScreen.setInvisible();
                if(addItemsScreen != null) {
                    addItemsScreen.setVisible();
                    addItemsScreen.setAddItemsMode(AddItemsScreen.Mode.MAKE_ORDER);
                }
                if(finalizeOrderScreen != null) finalizeOrderScreen.setInvisible();
                break;
            case WAIT_NEW_ORDER:
                newOrderCurrentMode = Mode.WAIT_NEW_ORDER;
                if(selectClientScreen!=null) selectClientScreen.setInvisible();
                if(addItemsScreen != null){
                    addItemsScreen.setVisible();
                    addItemsScreen.setAddItemsMode(AddItemsScreen.Mode.WAIT_NEW_ORDER);
                }
                if(finalizeOrderScreen != null) finalizeOrderScreen.setInvisible();
                break;
            case ENDING_ORDER:
                newOrderCurrentMode = Mode.ENDING_ORDER;
                if(selectClientScreen!=null) selectClientScreen.setInvisible();
                if(addItemsScreen != null) addItemsScreen.setInvisible();
                if(finalizeOrderScreen != null) finalizeOrderScreen.showEndOrder();
                break;
        }
    }
    /*****Listeners************************/
    @Override
    public void onClientSelected(Client client, Establishment establishment) {
        clientID = client.getClientId();
        clientCode = client.getCodClient();
        establishmentID = establishment.getEstablishmentId();
        itemsToSend = new ArrayList<AddedItem>();

        addItemsScreen.setCodSelectedCompany(codSelectedCompany);
        addItemsScreen.setEstablishmentName(establishment.getNomeFantasia());

        setNewOrderMode(Mode.WAIT_NEW_ORDER);
        initOrder();
        addItemsScreen.startNewOrder();
    }

    @Override
    public void onEstabParamsReturn(EstabParamsDefault estabParamsDefault) {
        System.out.println("CALL - onEstabParamsReturn");
        this.estabParamsDefault = estabParamsDefault;
        addItemsScreen.selectPriceTable(estabParamsDefault.getTprvenId());
    }

    @Override
    public void newOrderButtonClick() {
        itemsToSend = new ArrayList<AddedItem>();
        initOrder();
    }

    @Override
    public void initializeAddingItems() {

        addItemsScreen.setNewOrder(currentOrder);
        addItemsScreen.setAddedItems(itemsToSend);

        setNewOrderMode(Mode.MAKE_ORDER);
        getCompanyParams();
        finalizeOrderScreen.setCodSelectedCompany(codSelectedCompany);
        //initOrder();
    }

    public void setOrderToEdit(Order order,ArrayList<AddedItem> items){
        clientID = order.getClientId();
        clientCode = "0000";
        establishmentID = order.getEstablishmentId();

        currentOrder = order;
        itemsToSend = items;

        orderManager.setOrder(currentOrder);

        addItemsScreen.setCodSelectedCompany(codSelectedCompany);
        addItemsScreen.setEstablishmentName(order.getNomeEstab());
        addItemsScreen.startNewOrder();
        selectClientScreen.getEstabParamsForEditOrder(clientID, establishmentID);
        //addItemsScreen.selectPriceTable(currentOrder.getPriceTableId());
    }

    @Override
    public void finalizeAddingItems(ArrayList<AddedItem> itemsAdded, String chosePriceTable) {
        itemsToSend = itemsAdded;

        currentOrder.setPriceTableId(chosePriceTable);
        finalizeOrderScreen.setOrder(currentOrder);
        setNewOrderMode(Mode.ENDING_ORDER);
        //orderManager.addItemsToOrder(itemsToSend);
        orderManager.getOrderValues();

        //finalizeOrderScreen.setClientID(selectedClient.getClientId());
        finalizeOrderScreen.setParamsSelectedCompany(paramsSelectedCompany);
        finalizeOrderScreen.setClientAndEstablishment(clientCode, clientID, establishmentID, estabParamsDefault);
        //finalizeOrderScreen.setClientEstablishment(selectedEstablishment);
    }

    @Override
    public void finalizeOrder(Order order) {
        currentOrder = order;
        orderManager.setOrder(order);
        orderManager.sendOrderAndFinalize();
    }

    @Override
    public void saveOrder(Order order) {
        currentOrder = order;
        orderManager.setOrder(order);
        orderManager.sendOrderToServer();
    }

    @Override
    public void backButtonClick(Order order) {
        currentOrder = order;
        addItemsScreen.setAddedItems(itemsToSend);
        setNewOrderMode(Mode.MAKE_ORDER);
        addItemsScreen.setVisible();
        finalizeOrderScreen.setInvisible();
    }

    @Override
    public void addItemsScreenBackButtonClick() {
        currentOrder = null;
        itemsToSend = new ArrayList<AddedItem>();
        setNewOrderMode(Mode.SELECT_CLIENT);
    }



    /**************************************/
    private void getCompanyParams(){
        CompanyParameters compParams = null;

        if(mServerDataCacheBinder != null) //ve se tem na cache
            compParams =  mServerDataCacheBinder.getCompanyParams(codSelectedCompany);
        if(compParams == null) //busca no servidor caso contrario
            ServerConnection.getCompanyParamsDefault(String.valueOf(codSelectedCompany), NewOrderFragment.this);
        else initCompanyParams(compParams); //inicializa com o valor buscado na cache

        ArrayList<PriceTable> priceTables = null;
        if(mServerDataCacheBinder != null) {
            priceTables = mServerDataCacheBinder.getCompanyPriceTable(codSelectedCompany);
        }
        if(priceTables == null || priceTables.size() == 0){
            ServerConnection.getCompanyPriceTable(codSelectedCompany, NewOrderFragment.this);
        }else {
            addItemsScreen.setPriceTableList(priceTables);
            addItemsScreen.selectPriceTable(paramsSelectedCompany.getPriceTable());
        }

        ArrayList<UnitOfMeasurement> unitOfMeasurements = null;
        if(mServerDataCacheBinder != null) {
            unitOfMeasurements = mServerDataCacheBinder.getUnitsOfMeasurements(codSelectedCompany);
        }
        if(unitOfMeasurements == null || unitOfMeasurements.size() == 0) {
            ServerConnection.getUnitsOfMeasurement(codSelectedCompany, NewOrderFragment.this);
        } else {
            addItemsScreen.setUnitsOfMeasurement(unitOfMeasurements);
        }

    }

    private void initCompanyParams(CompanyParameters params){
        if(params == null){
            setNewOrderMode(Mode.WAIT_NEW_ORDER);
            ShowMessage.alertDialog(getActivity(), R.string.error_missing_company_params);

        } else {
            paramsSelectedCompany = params;
        }
    }

    @Override
    public void orderInitialized(Order order) {
        currentOrder = order;
        addItemsScreen.setNewOrder(currentOrder);
        //if(newOrderCurrentMode != Mode.ENDING_ORDER){ //nao esta finalizando o pedido, apenas inicializando
        //    finalizeOrderScreen.setNewOrder(currentOrder);
        //    setNewOrderMode(Mode.ENDING_ORDER);
        //    orderManager.addItemsToOrder(itemsToSend);
        //} //else { //pedido foi finalizado
          //  setNewOrderMode(Mode.SELECT_CLIENT);
            /*ShowMessage.alertDialogSaved(getActivity(), R.string.message_save_order,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            switch (which) {
                                case DialogInterface.BUTTON_NEGATIVE:

                                    break;
                                case DialogInterface.BUTTON_POSITIVE:
                                    currentOrder = null;
                                    setNewOrderMode(Mode.SELECT_CLIENT);
                                    break;
                            }
                        }
                    });*/
        //}
    }

    @Override
    public void orderFinalized(Order order) {
        currentOrder = null;
        setNewOrderMode(Mode.SELECT_CLIENT);
    }


    @Override
    public void orderFromSaveToFinalized(String orderId) {
    }

    @Override
    public void onValorBrutoReturn(String valorBruto) {
        finalizeOrderScreen.setValorBruto(valorBruto);
    }

    @Override
    public void onValorLiquidoReturn(String valorLiquido) {
        finalizeOrderScreen.setValorLiquido(valorLiquido);
    }

    @Override
    public void onItemsAdded(ArrayList<AddedItem> itemsSent) {
        itemsToSend = itemsSent;
    }

    @Override
    public void onItemRemoved(String itemId) {
    }

    @Override
    public void onItemAdded(AddedItem item) {
    }

    @Override
    public void orderRemoved(String resultString) {
    }

    private void initOrder(){
        User user = mServerDataCacheBinder.getCurrentUser();

        orderManager.initOrder(user, paramsSelectedCompany, clientID,establishmentID);
    }

    /******Web services callbacks*****/
    @Override
    public void OnWebServiceCompanyParamsDefaultReturn(CompanyParameters params) {
        //adiciona na cache
        mServerDataCacheBinder.addCompanyParams(codSelectedCompany, params);
        initCompanyParams(params);
    }

    @Override
    public void failedOnRetrieveCompanyParamsDefault() {

        ShowMessage.alertDialog2(getActivity(), R.string.makeorder_failongetcompanyparams,
                new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        switch (which) {
                            case DialogInterface.BUTTON_NEGATIVE:
                                getActivity().finish();
                                break;
                            case DialogInterface.BUTTON_POSITIVE:
                                ServerConnection.getCompanyParamsDefault(String.valueOf(codSelectedCompany), NewOrderFragment.this);
                                break;
                        }
                    }
                });
    }

    @Override
    public void failedOnRetrivePriceTables() {

    }

    @Override
    public void OnWebServicePriceTablesReturn(ArrayList<PriceTable> priceTables) {
        //adiciona na cache
        mServerDataCacheBinder.addCompanyPriceTable(codSelectedCompany, priceTables);
        addItemsScreen.setPriceTableList(priceTables);
        if(paramsSelectedCompany != null) addItemsScreen.selectPriceTable(paramsSelectedCompany.getPriceTable());
    }

    @Override
    public void OnWebServiceUnitsOfMeasurementReturn(ArrayList<UnitOfMeasurement> unitOfMeasurementArrayList) {
        mServerDataCacheBinder.addUnitsOfMeasurement(codSelectedCompany, unitOfMeasurementArrayList);
        addItemsScreen.setUnitsOfMeasurement(unitOfMeasurementArrayList);
    }

    @Override
    public void failedGetUnitsOfMeasurement() {

    }

    @Override
	public void refresh() {
		// TODO Auto-generated method stub
	}

    public void stopOrderRemovedInSaveScreen(String orderId){
        if(currentOrder != null){
            if(currentOrder.getId().equals(orderId)) {
                orderFinalized(null);
            }
        }
    }

    /*********************************/
}